﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tunnel.Devices.DeviceEntity;
using Tunnel.Devices.DeviceEntity.Lamp;
using Tunnel.Entity;
using Tunnel.Tools.FcmsTools;

namespace Tunnel.Tools
{
    public static class DataDeal
    {

        /// <summary>
        /// 发送指令
        /// </summary>
        /// <param name="deviceID">设备ID</param>
        /// <param name="paramName">变量名</param>
        /// <param name="paramValue">变量值</param>
        public static void SendCommand(string deviceID, string paramName, string paramValue)
        {
            DBHelper dh = new DBHelper();
            dh.RunCommandAsync("INSERT INTO R_Command(CommandID, DeviceID, ParamName, ParamValue, UpdateTime, UpdateBy, Runned) VALUES(@commandid, @deviceid, @paramname, @paramvalue, GETDATE(),@user, 0)", new SqlParameter("@commandid", DBHelper.GetGuid), new SqlParameter("@deviceid", deviceID), new SqlParameter("@paramname", paramName), new SqlParameter("@paramvalue", paramValue), new SqlParameter("@user", Global.UserID));
        }
        /// <summary>
        /// 异步获取设备的变量名
        /// </summary>
        /// <param name="deviceID">设备ID</param>
        /// <returns>变量名表格</returns>
        public static Task<DataTable> ReadParamAsync(string deviceID)
        {
            DBHelper dh = new DBHelper();
            return dh.GetTableAsync("select * from R_RunStatus where DeviceID=@deviceid", new SqlParameter("@deviceid", deviceID));
        }
        /// <summary>
        /// 同步获取设备的变量名
        /// </summary>
        /// <param name="deviceID">设备ID</param>
        /// <returns>变量名表格</returns>
        public static DataTable ReadParam(string deviceID)
        {
            DBHelper dh = new DBHelper();
            return dh.GetTable("select * from R_RunStatus where DeviceID=@deviceid", new SqlParameter("@deviceid", deviceID));
        }
        /// <summary>
        /// 记录操作日志
        /// </summary>
        /// <param name="deviceId">设备ID</param>
        /// <param name="deviceType">设备类别</param>
        /// <param name="detail">操作细节</param>
        public static async void LogDB(string deviceId, string deviceType, string detail)
        {
            SqlCommand insertLog = new SqlCommand();
            insertLog.CommandText = "INSERT INTO [H_Log] ( [LogID],[UserID],[DeviceType],[DeviceID],[Detail],[UpdateTime] ) VALUES (@id,@userid,@devicetype,@deviceid,@detail,GETDATE())";
            insertLog.Parameters.Add(new SqlParameter("@id", DBHelper.GetGuid));
            insertLog.Parameters.Add(new SqlParameter("@userid", Global.UserID));
            insertLog.Parameters.Add(new SqlParameter("@devicetype", deviceType));
            insertLog.Parameters.Add(new SqlParameter("@deviceid", deviceId));
            insertLog.Parameters.Add(new SqlParameter("@detail", detail));

            await (new DBHelper()).RunCommandAsync(insertLog);
        }
        /// <summary>
        /// 在主界面上显示消息
        /// </summary>
        /// <param name="message">消息内容</param>
        public static void ShowMessage(string message)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(DateTime.Now.ToString());
            stringBuilder.Append("    ");
            stringBuilder.Append(message);
            Program.MainForm.MessageLabel.Invoke(new EventHandler(delegate { Program.MainForm.MessageLabel.Text = stringBuilder.ToString(); }));
            
        }
        public static void RunPlan(List<(string, string, string, string, string)> planInfoElements, BackgroundWorker backgroundWorker)
        {
            BackgroundWorker bwRunPlan = backgroundWorker;
            if (backgroundWorker != null)
            {
                bwRunPlan.ReportProgress(10, "开始下发指令");
                ShowMessage("开始下发指令");
            }
            foreach (var planInfoElement in planInfoElements)
            {
                string deviceName = planInfoElement.Item1;
                string deviceStatus = planInfoElement.Item2;//预案中准备执行的设备状态
                string deviceID = planInfoElement.Item3;
                string deviceTypeID = planInfoElement.Item4;
                string devicePlayListID = planInfoElement.Item5;

                switch (deviceTypeID)
                {
                    case "TS": //交通信号灯段
                        {
                            string GreenId = string.Empty, RedId = string.Empty, YellowId = string.Empty, TurnId = string.Empty;
                            DataTable dtParamIDTable = ReadParam(deviceID);
                            foreach (DataRow item in dtParamIDTable.Rows)
                            {
                                switch (item["ParamStatus"].ToString())
                                {
                                    case "GREEN": GreenId = item["ParamName"].ToString(); break;
                                    case "RED": RedId = item["ParamName"].ToString(); break;
                                    case "YELLOW": YellowId = item["ParamName"].ToString(); break;
                                    case "TURN": TurnId = item["ParamName"].ToString(); break;
                                }
                            }
                            switch (deviceStatus)
                            {
                                case "红灯": SendCommand(deviceID, RedId, "1"); ; break;
                                case "黄灯": SendCommand(deviceID, YellowId, "1"); ; break;
                                case "绿灯": SendCommand(deviceID, GreenId, "1"); ; break;
                                case "左转": SendCommand(deviceID, TurnId, "1"); ; break;
                                default: break;
                            }
                        }
                        break;
                    case "FCMS": //情报板段
                        {
                            FcmsProtocol fcmsProtocol = new FcmsProtocol();
                            List<string> savelog = new List<string>();
                            DBHelper dh = new DBHelper();
                            string fcmsid = deviceID;
                            string playlistid = devicePlayListID;
                            string sql = "select * from R_FcmsStatus where FCMSID = @fcmsid";
                            SqlCommand command = new SqlCommand(sql);
                            command.Parameters.Add(new SqlParameter("@fcmsid", fcmsid));
                            DataTable dtFcms = dh.GetTable(command);

                            string paramName = dtFcms.Rows[0]["ParamName"].ToString();
                            string controlSwitch = dtFcms.Rows[0]["ControlSwitch"].ToString();

                            DBHelper dh2 = new DBHelper();
                            string sql2 = "select * from M_PlayListInfo where PlayListID = @playlistid";
                            SqlCommand command2 = new SqlCommand(sql2);
                            command2.Parameters.Add(new SqlParameter("@playlistid", devicePlayListID));
                            DataTable dtPlayList = dh2.GetTable(command2);

                            FcmsPlayList fcmsPlayList = new FcmsPlayList();
                            List<byte> file = new List<byte>();
                            fcmsPlayList.ClearItem();
                            foreach (DataRow dr in dtPlayList.Rows)
                            {
                                DisplayElement element = new DisplayElement();
                                element.Msg = dr["Text"].ToString();
                                element.MsgX = dr["TextX"].ToString();
                                element.MsgY = dr["TextY"].ToString();
                                element.Delay = (int.Parse(dr["StayTime"].ToString()) * 100).ToString();
                                element.FontSize = dr["FontSize"].ToString() + dr["FontSize"].ToString();
                                element.Colour = dr["FontColor"].ToString();
                                savelog.Add(element.ToString());
                                fcmsPlayList.AddItem(element);
                            }
                            file = fcmsPlayList.GetPlayList();
                            bool successed = false;

                            using (StreamWriter writer = new StreamWriter(Application.StartupPath + @"\\play.lst", false, Encoding.Default))
                            {
                                writer.Write(Encoding.Default.GetString(file.ToArray()));                                
                                if (paramName.Contains("PLC"))
                                {
                                    successed = fcmsProtocol.UploadFileBySql("play.lst", file, fcmsid, paramName, controlSwitch);
                                }
                                if (paramName.Contains("COM"))
                                {
                                    successed = fcmsProtocol.UploadFileBySp("play.lst", file, fcmsid, paramName);
                                }
                                if (paramName.Contains("IP"))
                                {
                                    string[] ipInfo = paramName.Split(':');
                                    System.Net.IPAddress ipAddress = System.Net.IPAddress.Parse(ipInfo[1]);
                                    successed = fcmsProtocol.UploadFileByNet("play.lst", file, fcmsid, ipAddress, int.Parse(ipInfo[2]));
                                }
                            }
                            if (successed)
                            {
                                DBHelper sdh = new DBHelper();
                                string sql3 = $"UPDATE [R_FcmsStatus] SET [PlayListID]='{ playlistid }' WHERE [FCMSID]='{ fcmsid }'";
                                string fcmstext = "";
                                foreach (var item in savelog)
                                {
                                    fcmstext = fcmstext + " " + item;
                                }
                                string sql4 = $"insert into H_FCMSLog(FLogID,FCMSID,FCMSTEXT,UserID,UpdateTime) VALUES ('{ DBHelper.GetGuid }','{ fcmsid }','{ fcmstext }','{ Global.UserID }','{ DateTime.Now.ToString() }')";
                                sdh.RunTransactionCommands(new string[] { sql3, sql4 });
                                ShowMessage("情报板发送成功");
                            }
                        }
                        break;
                    case "Light":
                        {
                            string ParamName = string.Empty;
                            DataTable dtParamIDTable = ReadParam(deviceID);
                            foreach (DataRow item in dtParamIDTable.Rows)
                            {
                                switch (item["ParamStatus"].ToString())
                                {
                                    case "ON": ParamName = item["ParamName"].ToString(); break;
                                }
                                switch (deviceStatus)
                                {
                                    case "点亮": SendCommand(deviceID, ParamName, "1"); ; break;
                                    case "熄灭": SendCommand(deviceID, ParamName, "0"); ; break;
                                    default: break;
                                }
                            }
                        }
                        break;
                    default: break;

                }                
            }            
            int i = 0;
            if (backgroundWorker != null)
            {
                bwRunPlan.ReportProgress(30, "风机控制开始");
                ShowMessage("正在按照预案控制风机");
            }            
            foreach (var planInfoElement in planInfoElements)
            {
                string deviceName = planInfoElement.Item1;
                string deviceStatus = planInfoElement.Item2;
                string deviceID = planInfoElement.Item3;
                string deviceTypeID = planInfoElement.Item4;
                string devicePlayListID = planInfoElement.Item5;

                if (deviceTypeID == "FAN")
                {
                    DataTable dtParamIDTable = ReadParam(deviceID);
                    string ZzName = string.Empty, FzName = string.Empty, TzName = string.Empty;
                    foreach (DataRow item in dtParamIDTable.Rows)
                    {
                        switch (item["ParamStatus"].ToString())
                        {
                            case "ZZ": ZzName = item["ParamName"].ToString(); break;
                            case "FZ": FzName = item["ParamName"].ToString(); break;
                            case "TZ": TzName = item["ParamName"].ToString(); break;

                        }
                    }
                    int fanSeconds = FanTimeControl.getSeconds();
                    if (fanSeconds != 0)
                    {
                        System.Threading.Thread.Sleep(fanSeconds * 1000);
                        if (backgroundWorker != null)
                        {
                            bwRunPlan.ReportProgress(40 + 10 * i, "正在等待风机控制间隔");
                        }
                    }
                    switch (deviceStatus)
                    {
                        case "正转": SendCommand(deviceID, ZzName, "1"); break;
                        case "反转": SendCommand(deviceID, ZzName, "1"); break;
                        case "停止": SendCommand(deviceID, ZzName, "1"); break;
                        default: break;
                    }
                    FanTimeControl.LastFanTime = DateTime.Now;
                }
            }
            if (backgroundWorker != null)
            {
                bwRunPlan.ReportProgress(100, "指令下发完成");
                ShowMessage("预案执行完成");
            }
        }

    }
}
